package com.bingxue.edu.common.job;

import cn.hutool.core.util.StrUtil;
import com.bingxue.edu.common.config.NotifyConfigProperties;
import com.bingxue.edu.common.enums.StudentClassEnum;
import com.bingxue.edu.common.wechat.WxMessageManager;
import com.bingxue.edu.framework.job.DynamicJob;
import com.bingxue.edu.management.education.service.LessonService;
import com.bingxue.edu.management.report.model.resp.LessonSignInTipModel;
import com.mybatisflex.core.query.QueryMethods;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.cp.bean.message.WxCpMessage;
import org.quartz.DisallowConcurrentExecution;
import org.quartz.JobExecutionContext;
import org.springframework.scheduling.quartz.QuartzJobBean;

import java.time.LocalDate;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;

import static com.bingxue.edu.common.constant.DateConstants.FORMATTER_TIME_HHmm_CN;
import static com.bingxue.edu.management.education.model.entity.table.ClassInfoTableDef.CLASS_INFO;
import static com.bingxue.edu.management.education.model.entity.table.LessonStudentTableDef.LESSON_STUDENT;
import static com.bingxue.edu.management.education.model.entity.table.LessonTableDef.LESSON;
import static com.mybatisflex.core.query.QueryMethods.case_;
import static com.mybatisflex.core.query.QueryMethods.ifNull;
import static com.mybatisflex.core.query.QueryMethods.number;
import static com.mybatisflex.core.query.QueryMethods.sum;

/**
 * @author panbo
 * @since 2025/2/10
 */
@Slf4j
@DisallowConcurrentExecution
@RequiredArgsConstructor
@DynamicJob(name="课次补签提醒任务", cron = "0 0 7 * * ? ", paramClass = LessonSignInTipJobParam.class)
public class LessonSignInTipJob extends QuartzJobBean {

    private final NotifyConfigProperties notifyConfigProperties;
    private final WxMessageManager wxMessageManager;
    private final LessonService lessonService;

    private void sendNotify(LessonSignInTipModel lesson) {
        try {
            LinkedList<String> userCodeList = new LinkedList<>();
            if (StrUtil.isNotEmpty(lesson.getLeadTeacherCode())) {
                userCodeList.push(lesson.getLeadTeacherCode());
            }
            if (StrUtil.isNotEmpty(lesson.getAssistTeacherCode())) {
                userCodeList.push(lesson.getAssistTeacherCode());
            }
            if (userCodeList.isEmpty()) {
                return;
            }
            WxCpMessage wxCpMessage = wxMessageManager.buildMiniAppMessage(String.join("|", userCodeList));
            wxCpMessage.setPage(String.format("pages/class/lesson?id=%s", lesson.getId()));
            wxCpMessage.setTitle("课程补签通知");
            wxCpMessage.setDescription("请及时签到，以免影响绩效计算");
            LinkedHashMap<String, String> items = new LinkedHashMap<>();
            items.put("签到状态", String.format("%d/%d人", lesson.getSignInCount(), lesson.getTotalCount()));
            items.put("课次", lesson.getTitle());
            items.put("班级", lesson.getClassName());
            items.put("上课时间", lesson.getStartTime().format(FORMATTER_TIME_HHmm_CN));
            wxCpMessage.setContentItems(items);
            wxMessageManager.sendMessage(wxCpMessage);
            Thread.sleep(500);
        } catch (Exception e) {
            log.warn("发送补签企业微信提醒[{}]失败：{}", lesson, e.getMessage());
        }
    }

    @Override
    protected void executeInternal(JobExecutionContext context) {
        log.info("课次补签提醒任务开始");
        if (!notifyConfigProperties.getLessonSignInTip().isTeacherWecomEnabled()) {
            return;
        }
        int beforeDays = 1;
        String beforeDaysStr = context.getJobDetail().getJobDataMap().getString("beforeDays");
        if (StrUtil.isNotEmpty(beforeDaysStr)) {
            beforeDays = Integer.parseInt(beforeDaysStr);
        }
        LocalDate today = LocalDate.now();

        List<LessonSignInTipModel> lessonList = lessonService.queryChain()
                .select(
                        LESSON.DEFAULT_COLUMNS,
                        ifNull(QueryMethods.count(), number(0)).as(LessonSignInTipModel::getTotalCount),
                        sum(case_(LESSON_STUDENT.SIGN_IN_STATUS).when(1).then(1).else_(0).end()).as(LessonSignInTipModel::getSignInCount),
                        CLASS_INFO.NAME.as(LessonSignInTipModel::getClassName)
                ).from(LESSON)
                .leftJoin(LESSON_STUDENT).on(LESSON_STUDENT.LESSON_ID.eq(LESSON.ID))
                .leftJoin(CLASS_INFO).on(CLASS_INFO.ID.eq(LESSON.CLASS_ID))
                .where(LESSON.LESSON_DATE.eq(today.minusDays(beforeDays)))
                    .and(LESSON_STUDENT.STUDENT_CLASS_STATUS.eq(StudentClassEnum.NORMAL))
                .groupBy(LESSON.ID)
                .withRelations()
                .listAs(LessonSignInTipModel.class);

        lessonList.stream()
                .filter(lesson -> lesson.getTotalCount() - lesson.getSignInCount() > 0)
                .forEach(this::sendNotify);
        log.info("课次补签提醒任务结束");
    }
}
